package com.mh.common;

import com.mh.pojo.User;
import com.mh.pojo.UserManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.util.ArrayList;
import java.util.List;

/**
 * Date:2023/4/18
 * author:zmh
 * description: WebSocket消息处理类
 **/

@Component
@Slf4j
public class MyWebSocketHandler implements WebSocketHandler {

    // 维护所有连接会话的列表
    private List<WebSocketSession> sessions = new ArrayList<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 将新连接的Session加入到集合中
//        session.sendMessage(new TextMessage(session.toString()));
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        // 获取前端传入的消息
        String payload = (String) message.getPayload();

        /**
         * 内容处理规则
         * 绑定连接：$$用户名
         * 私聊：@@目标用户 内容
         * 广播：**内容
         */

        // 绑定连接
        if(payload.startsWith("$$")){
            // 获取用户名
            String userName = payload.substring(2);
            log.info("新建连接，用户是:{}", userName);
            // 将当前用户连接加入管理员类进行管理
            UserManager.getInstance().add(session,new User(session, userName));
            // 加入session列表，用于广播
            this.sessions.add(session);
        }

        // 广播
        if(payload.startsWith("**")){
            // 判断是否绑定了连接
            if(!UserManager.getInstance().hasKey(session)){
                session.close();
                return;
            }
            // 获取广播内容-格式：**用户 广播内容
            String content = payload.substring(2);
            // 获取广播内容的用户名
            User user = UserManager.getInstance().get(session);
            String userName = user.getUserName();
            for (WebSocketSession s: sessions){
                s.sendMessage(new TextMessage( "**"+ userName + "**" +  content));
            }
        }

        // 私聊-@@目标用户 内容
        if(payload.startsWith("@@")){
            // 获取目标用户名
            int i = payload.indexOf(" ");
            String targetUserName = payload.substring(2, i);
            // 通过用户名获取目标用户的session
            WebSocketSession targetSession = UserManager.getInstance().getSessionByUserName(targetUserName);
            // 判断是否存在
            if (targetSession == null){
                session.sendMessage(new TextMessage("发送的用户不在线!"));
            }
            // 获取发送者的用户名
            User user = UserManager.getInstance().get(session);
            String sourceUserName = user.getUserName();
            // 获取私聊内容
            String privateContent = payload.substring(i + 1);
            // 发送私聊信息，格式：@@来源用户 内容
            targetSession.sendMessage(new TextMessage("@@" + sourceUserName + "@@" + privateContent));
        }


        // 判断前端传入消息，决定是否广播发送重载数据命令
        if ("maohe101".equals(payload)){
            // 判断是否绑定了连接
            if(!UserManager.getInstance().hasKey(session)){
                session.close();
                return;
            }
            // 广播重载命令
            for (WebSocketSession s: sessions){
                s.sendMessage(new TextMessage("reload"));
            }
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        // 处理错误的连接，将连接删除
        this.sessions.remove(session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        // 处理主动关闭的连接
        this.sessions.remove(session);
    }

    @Override
    public boolean supportsPartialMessages() {
        // 关闭部分消息的处理，等待所有消息到达后在做处理
        return false;
    }
}
